Cartographer_nnTrainers = Cartographer:NewModule("nnTrainers", "LibRockEvent-1.0", "LibRockDB-1.0", "LibRockConsole-1.0")
local mod = Cartographer_nnTrainers

mod:SetDatabase("nnTrainersDB", "nnTrainersDBPC")

local BC = Rock("Babble-Class-2.2")
local BT = Rock("Babble-Tradeskill-2.2")
local L = Rock("LibRockLocale-1.0"):GetTranslationNamespace("Cartographer_nnTrainers")

local gratuity = Rock("LibGratuity-3.0")

L:AddTranslations("enUS", function() return {
	["nnTrainers"] = true,
	["nnTrainers options."] = true,
	["Enable trainer mapnotes"] = true,
	["Enable autofilter"] = true,
	["Add a mapnote to show where your trainers are"] = true,
	["Filter"] = true,
	["Filter out trainers"] = true,
	["Select all"] = true,
	["Select none"] = true,
	["Auto select"] = true,
	["Automaticly select notes by depending on class and professions"] = true,
	["Icon alpha"] = true,
	["Alpha transparency of the icon"] = true,
	["Icon size"] = true,
	["Size of the icons on the map"] = true,
	["Show minimap icons"] = true,
	["Show trainer icons on the minimap"] = true,
	["Show minimap tracking icons"] = true,
    ["Show trainer tracking icons on the minimap"] = true,
	["Upgrade Notes"] = true,
	["Try to upgrade all old/questionmark notes"] = true,
		
	["Poison"] = true,
	["Misc"] = true,
	["Demon"] = true,
	["Pet"] = true,
	["Portal Trainer"] = true,
	["Riding"] = true,
	["Weapon Master"] = true,
	["Stable Master"] = true,
	["Trainer"] = true,
	["Journeyman"] = true,
	["Expert"] = true,
	["Artisan"] = true,
	["Master"] = true,
	["Professions"] = true,
	["Secondary Skills"] = true,
	
	["Demon Trainer"] = true,
	["Demon"] = true,
} end)

L:AddTranslations("zhTW", function() return {
	["nnTrainers"] = "導師",
	["nnTrainers options."] = "導師選項",
	["Enable trainer mapnotes"] = "啟用導師標記",
	["Enable autofilter"] = "啟用自動篩選",
	["Add a mapnote to show where your trainers are"] = "在地圖標記上增加導師位置",
	["Filter"] = "篩選",
	["Filter out trainers"] = "篩選導師",
	["Select all"] = "全選",
	["Select none"] = "不選",
	["Auto select"] = "自動選取",
	["Automaticly select notes by depending on class and professions"] = "以職業及專業技能自動選取",
	["Icon alpha"] = "圖示透明度",
	["Alpha transparency of the icon"] = "設定圖示的透明度",
	["Icon size"] = "圖示大小",
	["Size of the icons on the map"] = "圖示在地圖上顯示的大小",
	["Show minimap icons"] = "顯示小地圖圖示",
	["Show trainer icons on the minimap"] = "在小地圖顯示導師圖示",
	["Show minimap tracking icons"] = "顯示追蹤圖示",
    ["Show trainer tracking icons on the minimap"] = "在小地圖顯示追蹤標誌圖示",
	["Upgrade Notes"] = "更新標記",
	["Try to upgrade all old/questionmark notes"] = "更新過時及問號標記",
		
	["Poison"] = "毒藥",
	["Misc"] = "其它",
	["Demon"] = "惡魔",
	["Pet"] = "寵物",
	["Portal Trainer"] = "傳送門導師",
	["Riding"] = "飛騎管理員",
	["Weapon Master"] = "武器大師",
	["Stable Master"] = "獸欄管理員",
	["Trainer"] = "導師",
	["Journeyman"] = "初級",
	["Expert"] = "高級",
	["Artisan"] = "專業",
	["Master"] = "大師",
	["Professions"] = "專業技能",
	["Secondary Skills"] = "第二技能",
	
	["Demon Trainer"] = "惡魔訓練師",
	["Demon"] = "惡魔",
} end)

L:AddTranslations("deDE", function() return {
	--["MapNotes"] = "MapNotes",
	--["MapNote options. (Requires Cartographer)"] = "MapNote-Optionen. (ben\195\182tigt Cartographer)",
	["Enable trainer mapnotes"] = "Kartennotizen f\195\188r Lehrer aktivieren",
	["Enable autofilter"] = "Automatische Filterung aktivieren",
	["Add a mapnote to show where your trainers are"] = "F\195\188gt eine Notiz auf der Karte hinzu, um die Standorte der Lehrer anzuzeigen",
	["Filter"] = "Filter",
	["Filter out trainers"] = "Lehrer herausfiltern",
	["Select all"] = "Alle ausw\195\164hlen",
	["Select none"] = "Keinen ausw\195\164hlen",
	["Auto select"] = "Automatisch ausw\195\164hlen",
	["Automaticly select notes by depending on class and professions"] = "W\195\164hlt automatisch die Notizen aus, abh\195\164ngig von Klasse und Berufen",
	["Icon alpha"] = "Icon-Transparenz",
	["Alpha transparency of the icon"] = "Alpha-Tranparenz des Icons",
	["Icon size"] = "Icon-Gr\195\182\195\159e",
	["Size of the icons on the map"] = "Gr\195\182\195\159e des Icons auf der Karte",
	["Show minimap icons"] = "Minimap-Icon anzeigen",
	["Show trainer icons on the minimap"] = "Zeigt Bergbau-Icons auf der Minimap",
		
	--["Portal"] = "Portal",
	["Pet"] = "Haustier",
	["Misc"] = "Sonstiges",
	["Demon"] = "D\195\164mon",
	["Poison"] = "Gifte",
	["Riding"] = "Reiten",
	["Weapon Master"] = "Waffenmeister",
	["Stable Master"] = "Stallmeister",
	["Trainer"] = "Lehrer",
	["Journeyman"] = "Geselle",
	["Expert"] = "Experte",
	["Artisan"] = "Fachmann",
	["Master"] = "Meister",
	["Professions"] = "Berufe",
	["Secondary Skills"] = "Sekund\195\164re Fertigkeiten",
	
	["Demon Trainer"] = "D\195\164monenausbilder",
	["Demon"] = "D\195\164mon",
} end)

L:AddTranslations("frFR", function() return {
	--["MapNotes"] = "MapNotes",
	--["MapNote options. (Requires Cartographer)"] = "Options MapNote. (n\195\169cessite Cartographer)",
	["Enable trainer mapnotes"] = "Activer les notes pour les ma\195\174tres",
	["Enable autofilter"] = "Activer le filtre automatique",
	["Add a mapnote to show where your trainers are"] = "Ajouter une note pour indiquer o?se situent vos ma\195\174tres",
	["Filter"] = "Filtre",
	["Filter out trainers"] = "Filtrer les ma\195\174tres",
	["Select all"] = "Selectionner tout",
	["Select none"] = "Selectionner aucun",
	["Auto select"] = "Selection automatique",
	["Automaticly select notes by depending on class and professions"] = "Selectionne automatiquement les notes en fonction de la classe et des professions",
	["Icon alpha"] = "Transparence",
	["Alpha transparency of the icon"] = "Transparence pour l'icone",
	["Icon size"] = "Taille de l'icone",
	["Size of the icons on the map"] = "Tailles des icones sur la carte",
	["Show minimap icons"] = "Affiche les icones sur la minimap",
	["Show trainer icons on the minimap"] = "Afficher les icones de minage sur la minimap",
		
	--["Portal"] = "Portal",
	["Pet"] = "Familier",
	["Misc"] = "Divers",
	["Demon"] = "D\195\169mon",
	["Poison"] = "Poison",
	["Riding"] = "Monte",
	["Weapon Master"] = "Ma\195\174tre d'arme",
	["Stable Master"] = "Ma\195\174tre des \195\169curies",
	["Trainer"] = "Ma\195\174tre",
	["Journeyman"] = "Compagnon",
	["Expert"] = "Expert",
	["Artisan"] = "Artisan",
	["Master"] = "Ma\195\174tre",
	["Professions"] = "M\195\169tiers",
	["Secondary Skills"] = "Comp\195\169tences secondaires",
	
	["Demon Trainer"] = "Ma\195\174tre des d\195\169mons",
	["Demon"] = "D\195\169mon",
} end)

L:AddTranslations("zhCN", function() return {
	--Chinese Simplify transled by 雪夜之狼@Feathermoon CN3
	--xionglingfeng@Gmail.com
	["nnTrainers"] = "训练师",
	["nnTrainers options."] = "训练师选项",
	["Enable trainer mapnotes"] = "启用训练师标记",
	["Enable autofilter"] = "启用自动筛选",
	["Add a mapnote to show where your trainers are"] = "在地图标记上增加训练师位置",
	["Filter"] = "筛选",
	["Filter out trainers"] = "筛选训练师",
	["Select all"] = "全选",
	["Select none"] = "全不选",
	["Auto select"] = "自动选择",
	["Automaticly select notes by depending on class and professions"] = "根据职业和专业技能自动选择",
	["Icon alpha"] = "图标透明度",
	["Alpha transparency of the icon"] = "设置图标的透明度",
	["Icon size"] = "图标大小",
	["Size of the icons on the map"] = "图标在地图上显示的大小",
	["Show minimap icons"] = "显示小地图图标",
	["Show trainer icons on the minimap"] = "在小地图显示训练师图标",
	["Show minimap tracking icons"] = "显示追踪图标",
    ["Show trainer tracking icons on the minimap"] = "在小地图显示追踪图标",
	["Upgrade Notes"] = "更新标记",
	["Try to upgrade all old/questionmark notes"] = "更新过时和问号标记",
		
	["Poison"] = "毒药",
	["Misc"] = "其它",
	["Demon"] = "恶魔",
	["Pet"] = "宠物",
	["Portal Trainer"] = "传送门训练师",
	["Riding"] = "飞行管理员",
	["Weapon Master"] = "武器大师",
	["Stable Master"] = "兽栏管理员",
	["Trainer"] = "训练师",
	["Journeyman"] = "初级",
	["Expert"] = "中级",
	["Artisan"] = "高级",
	["Master"] = "大师级",
	["Professions"] = "专业技能",
	["Secondary Skills"] = "第二专业技能",
	
	["Demon Trainer"] = "恶魔训练师",
	["Demon"] = "恶魔",
} end)
local icon_path = "Interface\\AddOns\\Cartographer_nnTrainers\\Artwork\\"
mod.icons = {
	["Alchemy"] = {
        text = BT["Alchemy"],
        path = icon_path .. "Alchemy",
    },
    ["Blacksmithing"] = {
        text = BT["Blacksmithing"],
        path = icon_path .. "Blacksmithing",
    },
	["Poison"] = {
        text = L["Poison"],
        path = icon_path .. "Poison",
    },
	["Cooking"] = {
        text = BT["Cooking"],
        path = icon_path .. "Cooking",
    },
    ["Misc"] = {
        text = L["Misc"],
        path = icon_path .. "Misc",
    },
    ["Demon"] = {
        text = L["Demon"],
        path = icon_path .. "Demon",
    },
	["Druid"] = {
        text = BC["Druid"],
        path = icon_path .. "Druid",
    },
	["Enchanting"] = {
        text = BT["Enchanting"],
        path = icon_path .. "Enchanting",
    },
	["Engineering"] = {
        text = BT["Engineering"],
        path = icon_path .. "Engineering",
    },
	["First Aid"] = {
        text = BT["First Aid"],
        path = icon_path .. "Firstaid",
    },
	["Fishing"] = {
        text = BT["Fishing"],
        path = icon_path .. "Fishing",
    },
	["Herbalism"] = {
        text = BT["Herbalism"],
        path = icon_path .. "Herbalism",
    },
	["Hunter"] = {
        text = BC["Hunter"],
        path = icon_path .. "Hunter",
    },
	["Jewelcrafting"] = {
        text = BT["Jewelcrafting"],
        path = icon_path .. "Jewelcrafting",
    },
	["Leatherworking"] = {
        text = BT["Leatherworking"],
        path = icon_path .. "Leatherworking",
    },
	["Mage"] = {
        text = BC["Mage"],
        path = icon_path .. "Mage",
    },
	["Mining"] = {
        text = BT["Mining"],
        path = icon_path .. "Mining",
    },
	["Paladin"] = {
        text = BC["Paladin"],
        path = icon_path .. "Paladin",
    },
	["Pet"] = {
        text = L["Pet"],
        path = icon_path .. "Pet",
    },
	["Priest"] = {
        text = BC["Priest"],
        path = icon_path .. "Priest",
    },
	["Portal Trainer"] = {
        text = L["Portal Trainer"],
        path = "Interface\\Icons\\Spell_Arcane_PortalIronForge",
    },
	["Rogue"] = {
        text = BC["Rogue"],
        path = icon_path .. "Rogue",
    },
	["Shaman"] = {
        text = BC["Shaman"],
        path = icon_path .. "Shaman",
    },
	["Skinning"] = {
        text = BT["Skinning"],
        path = icon_path .. "Skinning",
    },
	["Tailoring"] = {
        text = BT["Tailoring"],
        path = icon_path .. "Tailoring",
    },
	["Warlock"] = {
        text = BC["Warlock"],
        path = icon_path .. "Warlock",
    },
	["Warrior"] = {
        text = BC["Warrior"],
        path = icon_path .. "Warrior",
    },
	["Weapon Master"] = {
        text = L["Weapon Master"],
        path = "Interface\\Icons\\INV_Sword_12",
    },
}

function mod:OnInitialize()
	self:SetDatabaseDefaults("faction", {
		TrainerNotes = {}
	})

	self:SetDatabaseDefaults("profile", {
		autoFilterIcons = true,
		iconAlpha = 1,
		iconScale = 1,
		minicons = true,
	})

	self:SetDatabaseDefaults("char", {
		filter = {
			['*'] = true,
		},
	})	
	
	local options = {}
	
	options.toggle = {
		name = Cartographer.L["Enabled"],
		desc = Cartographer.L["Suspend/resume this module."],
		type = 'toggle',
		order = 10,
		get = function() return Cartographer:IsModuleActive(self) end,
		set = function() Cartographer:ToggleModuleActive(self) end,
	}
	
	options.minicons = {
		name = L["Show minimap icons"],
		desc = L["Show trainer icons on the minimap"],
		type = 'toggle',
		set = "ToggleShowingMinimapIcons",
		get = "IsShowingMinimapIcons",
		order = 20,
	}
	
	options.tracking = {
		name = L["Show minimap tracking icons"],
		desc = L["Show trainer tracking icons on the minimap"],
		type = 'toggle',
		set = "ToggleTracking",
		get = "IsTracking",
		order = 30,
	}
	
	options.autofilter = {
		type = 'toggle',
		name = L["Enable autofilter"],
		desc = L["Automaticly select notes by depending on class and professions"],
		get = function() return self.db.profile.autoFilterIcons end,
		set = function() self.db.profile.autoFilterIcons = not self.db.profile.autoFilterIcons end,
		order = 40,
	}
	
	options.transparency = {
		name = L["Icon alpha"],
		desc = L["Alpha transparency of the icon"],
		type = 'range',
		min = 0.1,
		max = 1,
		step = 0.05,
		isPercent = true,
		get = "GetIconAlpha",
		set = "SetIconAlpha",
		order = 50
	}
	
	options.scale = {
		name = L["Icon size"],
		desc = L["Size of the icons on the map"],
		type = 'range',
		min = 0.5,
		max = 2,
		step = 0.05,
		isPercent = true,
		get = "GetIconScale",
		set = "SetIconScale",
		order = 60
	}

	
	options.filter = {
		name = L["Filter"],
		desc = L["Filter out trainers"],
		type = 'group',
		order = 70,
		args = {
			selectall = {
				name = L["Select all"],
				desc = L["Select all"],
				type = 'execute',
				func = function()
					for k in pairs(self.icons) do
						self:ToggleShowingTrainer(k, true)
					end
				end,
				order = 1,
			},
			selectnone = {
				name = L["Select none"],
				desc = L["Select none"],
				type = 'execute',
				func = function()
					for k in pairs(self.icons) do
						self:ToggleShowingTrainer(k, false)
					end
				end,
				order = 2,
			},
			selectauto = {
				name = L["Auto select"],
				desc = L["Automaticly select notes by depending on class and professions"],
				type = 'execute',
				func = function() self:AutoNoteFilter() end,
				order = 3,
			},
			selectblank = {
				type = 'header',
				order = 4,
			}
		}
	}
	
	for k,v in pairs(self.icons) do
		local k = k
		options.filter.args[string.gsub(k, "%s", "-")] = {
			name = v.text,
			desc = v.text,
			type = 'toggle',
			get = function()
				return self:IsShowingTrainer(k)
			end,
			set = function(value)
				return self:ToggleShowingTrainer(k, value)
			end,
		}
	end
	
	Cartographer.options.args.nnTrainers = {
		type = 'group',
		name = L["nnTrainers"],
		desc = L["nnTrainers options."],
		disabled = function() return not Cartographer_Notes end,
		handler = self,
		args = options,
	}
end

function mod:OnEnable()
	if Cartographer_Notes then
        if not iconssregistered then
			for k,v in pairs(self.icons) do
                Cartographer_Notes:RegisterIcon(k, v)
            end
            iconssregistered = true
        end

        Cartographer_Notes:RegisterNotesDatabase("nnTrainers", self.db.faction.TrainerNotes, self)

		self:AddEventListener("TRAINER_SHOW")
		
		-- Warlocks have anoyying crybaby pets
		if select(2, UnitClass("player")) == "WARLOCK" then
			self:AddEventListener("MERCHANT_SHOW")
		end
		
		if self.db.profile.autoFilterIcons then
			self:AddEventListener("Blizzard", "PLAYER_LOGIN", "AutoNoteFilter")
		end
    else
        Cartographer:ToggleModuleActive(self, false)
    end
end

function mod:OnDisable()
    if Cartographer_Notes then
        Cartographer_Notes:UnregisterNotesDatabase("nnTrainers")
    end
end

function mod:TRAINER_SHOW()
	local trainerName, _ = UnitName("npc")
	local trainerType
	if IsTradeskillTrainer() then
		trainerType = GetTrainerServiceSkillLine(2)
	else
		trainerType = UnitClass("player")
	end
    gratuity:SetUnit("npc")
    local trainerSubType = gratuity:GetLine(2)
	if trainerSubType == L["Weapon Master"] or trainerSubType == L["Portal Trainer"] then
		trainerType = trainerSubType
	end
	
	self:AddTrainerNote(trainerName, trainerType, trainerSubType)
end

function mod:MERCHANT_SHOW()
	gratuity:SetUnit("npc")
    local trainerSubType = gratuity:GetLine(2)
	
	if string.find(trainerSubType, L["Demon Trainer"]) then 
		local trainerName, _ = UnitName("npc")
		self:AddTrainerNote(trainerName, L["Demon"], L["Demon Trainer"])
	end
end

function mod:AddTrainerNote(trainerName, trainerType, trainerSubType)
	if not trainerName or not trainerType or not trainerSubType then
		return false
	end
	
	local zone = GetRealZoneText()
	local x, y = GetPlayerMapPosition("player")
	
	if BT:HasReverseTranslation(trainerType) then
		trainerType = BT:GetReverseTranslation(trainerType)
	elseif BC:HasReverseTranslation(trainerType) then
		trainerType = BC:GetReverseTranslation(trainerType)
	else
		trainerType = L.reverse[trainerType] or trainerType
	end

	if self.icons[trainerType] then
		for zone, x, y, _, _, data in Cartographer_Notes:IterateNearbyNotes(zone, x, y, 10, "nnTrainers", 10, true) do
			if data.info == trainerName then
				Cartographer_Notes:DeleteNote(zone, x, y)
			end
		end

		Cartographer_Notes:SetNote(
			zone, x, y, trainerType, "nnTrainers",
			'title',  trainerSubType,
			'titleR', 0,
			'titleG', 1,
			'titleB', 0,
			'info', trainerName,
			'infoR', 1,
			'infoG', 1,
			'infoB', 1
		)
	end
end

function mod:IsNoteHidden(zone, id)
	return not self.db.char.filter[self.db.faction.TrainerNotes[zone][id].icon]
end

function mod:IsShowingTrainer(trainer)
	return self.db.char.filter[trainer]
end
function mod:ToggleShowingTrainer(trainer, value)
	if value == nil then
		value = not self.db.char.filter[trainer]
	end
	self.db.char.filter[trainer] = value
	Cartographer_Notes:RefreshMap()
end

function mod:GetIconScale()
	return self.db.profile.iconScale
end
function mod:SetIconScale(value)
	self.db.profile.iconScale = value
	Cartographer_Notes:RefreshMap()
end

function mod:GetIconAlpha()
	return self.db.profile.iconAlpha
end
function mod:SetIconAlpha(value)
	self.db.profile.iconAlpha = value
	Cartographer_Notes:RefreshMap()
end

function mod:GetNoteTransparency(zone,id,data)
	return self.db.profile.iconAlpha
end
function mod:GetNoteScaling(zone,id,data)
	return self.db.profile.iconScale
end
function mod:IsShowingMinimapIcons()
	return self.db.profile.minicons
end
function mod:ToggleShowingMinimapIcons()
	self.db.profile.minicons = not self.db.profile.minicons
	Cartographer_Notes:RefreshMap()
end
function mod:IsMiniNoteHidden(zone,id,data)
	return not self.db.profile.minicons
end

function mod:IsTracking(zone,id,data)
	return self.db.profile.isTracking
end
function mod:ToggleTracking()
	self.db.profile.isTracking = not self.db.profile.isTracking
	Cartographer_Notes:RefreshMap()
end

function mod:AutoNoteFilter()
	for k in pairs(self.icons) do
		self:ToggleShowingTrainer(k, false)
	end
	
	local header = nil
	local numSkills = GetNumSkillLines()
	for i=1, numSkills do
		local skillName, isHeader = GetSkillLineInfo(i)
		--Only save important skills, omitt unimportant stuff like languages and that you can wear cloth armor
		if isHeader then
			header = skillName
		elseif header and header == L["Professions"] or header == L["Secondary Skills"] then
			self:ToggleShowingTrainer(skillName, true)
		end
	end
	
	local localizedClass, class = UnitClass("player")
	if localizedClass and class then
		self:ToggleShowingTrainer(localizedClass, true)
		if class == "WARLOCK" then self:ToggleShowingTrainer("Demon", true) end
		if class == "HUNTER" then self:ToggleShowingTrainer("Pet", true) end
		if class == "ROGUE" then self:ToggleShowingTrainer("Poison", true) end
		if class == "MAGE" then self:ToggleShowingTrainer("Portal Trainer", true) end
	end
	
	--Always show
	self:ToggleShowingTrainer("Misc", true)
	self:ToggleShowingTrainer("Weapon Master", true)
end

function mod:ImportTrainerFuNotes()
	if TrainerFu and TrainerFu.db.namespaces and TrainerFu.db.namespaces.MapNotes.account.TrainerNotes then
		local localDB = self.db.faction.TrainerNotes
		local TrainerFuDB = TrainerFu.db.namespaces.MapNotes.account.TrainerNotes
		for zone, zoneTable in pairs(TrainerFuDB) do
			if type(zoneTable) == "table" then
				localDB[zone] = localDB[zone] or {}
				for coord, coordTable in pairs(zoneTable) do
					localDB[zone][coord] = coordTable
				end
			end
		end
		Cartographer_Notes:RefreshMap()
		self:Print("Trainer notes imported")
	else
		self:Print("Could not find TrainerFu notes DB")
	end
end
